<?php
require_once(CMF_CONTROLLER_PATH . 'ProtectedController.php');

/**
 * Table - generic wrapper class to allow easy generation of view/add/edit forms for tables with a primary key
 * @extends Controller
 */
class Table extends ProtectedController{
	var $model = null;
	var $show_delete = true;
	var $show_archive = true;
	var $show_live = true;
	var $controller = null;
	var $flash_messages = array(
		'save'				=> 'Item #{id} successfully saved.',
		'cancel' 			=> 'Edit of item #{id} cancelled.',
		'delete'			=> 'Item #{id} succesfully deleted.',
		'archive'			=> 'Item #{id} succesfully archived.',
		'restore'			=> 'Item #{id} succesfully restored.',
		'save_sort_order' 	=> 'Sort order successfully saved'
	);
	
	function Table($p = null){
		parent::ProtectedController($p);
		$this->redirect_url = $_SERVER['PHP_SELF'];
		$this->load->database();
		$this->load->library('html');
		$this->load->library('form_wrapper');
		$this->load->model('Generic_table');
		$this->load->helper('url');
		$this->load->helper('email');
		$this->load->library('TemplateParser');
		$this->controller = strtolower(get_class($this));
	}
	
	/* 
	 * index function has the ability to have a view and a data set passed to it by descendant classes
	 * descendant classes must also pass in a sort_field and sort_order now
	 */
	function index( $sort_field = null, $sort_order = null, $view = CMF_DEFAULT_TABLE_VIEW, $data = array()){
		$data['table'] = $this->model->getTable();
		$data['table_name'] = $this->model->getTableName();
		$data['controller'] = $this->controller;
		
		$data['id_field'] = $this->model->getIdField();
		$data['fields'] = $this->model->getFields();
		$data['view_fields'] = $this->model->getViewFields();
		$data['items'] = array();
		$this->model->getAllItems( $sort_field, $sort_order, $data['items']);
		$data['sortable'] = $this->model->isSortable();
		$data['sort_field'] = $sort_field;
		$data['sort_order']	= $sort_order;
		$data['show_archive'] = $this->model->hasArchive() && $this->show_archive;
		$data['show_delete'] = $this->show_delete;
		$data['show_live'] = $this->model->hasLiveFlag() && $this->show_live;
		$data['is_archive'] = false;
		$data['menu_view'] = isset($this->menu_view)?$this->menu_view:null;
		
		$this->load->view($view, $data);
	}
	
	function showArchive( $sort_field = null, $sort_order = null, $view = CMF_DEFAULT_TABLE_VIEW, $data = array()){
		$data['table'] = $this->model->getTable();
		$data['table_name'] = $this->model->getTableName();
		$data['controller'] = $this->controller;
		
		$data['id_field'] = $this->model->getIdField();
		$data['fields'] = $this->model->getFields();
		$data['view_fields'] = $this->model->getViewFields();
		$data['items'] = array();
		$this->model->getAllArchiveItems( $sort_field, $sort_order, $data['items']);
		$data['sortable'] = $this->model->isSortable();
		$data['sort_field'] = $sort_field;
		$data['sort_order']	= $sort_order;
		$data['show_archive'] = $this->model->hasArchive() && $this->show_archive;
		$data['show_delete'] = $this->show_delete;
		$data['show_live'] = false;
		$data['is_archive'] = true;
		$data['menu_view'] = isset($this->menu_view)?$this->menu_view:null;
		
		$this->load->view($view, $data);
	}
	
	function delete($id, $ajax = 0){
		$this->model->deleteItem($id);
		$this->templateparser->setString($this->flash_messages['delete']);
		$this->session->set_flashdata('cmf_message', $this->templateparser->evalTemplate(array('id' => $id)));
		if( $ajax ){
			echo '1:Item ' . $id . ' was deleted successfully';
		}else{
			//redirect('/admin/'.$this->model->getTable());
			redirect(CMF_URL . $this->controller);
		}
	}
	
	function _clearSessionImageUploads(){
		$this->session->unset_userdata('uploaded_images');
	}
	function _pushSessionImageUploads(){
		$image_uploads = $this->session->userdata('uploaded_images');
		if( $image_uploads ){
			$image_uploads_stack = $this->session->userdata('uploaded_images_stack');
			if( $image_uploads_stack ){
				$image_upload_stack = unserialize($image_uploads_stack);
			}
			if( !is_array($image_uploads_stack)){
				$image_uploads_stack = array();
			}
			$image_uploads_stack[] = $image_uploads;
			$this->session->set_userdata('uploaded_images_stack', serialize($image_uploads_stack));
			$this->session->unset_userdata('uploaded_images');
		}
	}
	function _popSessionImageUploads(){
		$image_uploads_stack = $this->session->userdata('uploaded_images_stack');
		if( $image_uploads_stack ){
			$image_uploads_stack = unserialize($image_uploads_stack);
			if( is_array($image_uploads_stack)){
				$image_uploads = array_pop($image_uploads_stack);
				$this->_clearSessionImageUploads();
				$this->session->set_userdata('uploaded_images', serialize($image_uploads));
				$this->session->set_userdata('uploaded_images_stack', serialize($image_uploads_stack));
			}
		}
	}
	
	function edit( $id = null, $view = CMF_DEFAULT_TABLE_EDIT_VIEW, $data = array() ){
		$this->_clearSessionImageUploads();
		if( !isset($data['item']) ){
			if( !empty($id) ){
				$data['item'] = $this->model->getItem( $id);
			}else{
				$data['item'] = $this->model->getEmptyItem();
			}
			$this->getTableAndFieldData($data, $id);
		}
		$this->load->library('form_validation');
		$this->load->helper('form');
		$this->load->view($view, $data);
	}
	
	function editAjax( $id = null, $view = CMF_DEFAULT_TABLE_AJAX_EDIT_VIEW, $data = array()){
		//$this->_pushSessionImageUploads();
		if( !isset($data['item']) ){
			if( !empty($id) ){
				$data['item'] = $this->model->getItem( $id);
			}else{
				$data['item'] = $this->model->getEmptyItem();
			}
			$this->getTableAndFieldData($data, $id);
		}
		
		$this->load->library('form_validation');
		$this->load->helper('form');
		$this->load->view($view, $data);
	}
	
	function editMultiple( $return = null ){
		if( $this->input->post('selected') && is_array($this->input->post('selected'))){
			if( $this->input->post('set_live') ){
				$this->model->setItemsLive($this->input->post('selected'));
			}else if( $this->input->post('set_not_live') ){
				$this->model->setItemsLive($this->input->post('selected'), 0);
			}else if( $this->input->post('archive') ){
				$this->model->archiveItems($this->input->post('selected'));
			}else if( $this->input->post('restore')){
				$this->model->archiveItems($this->input->post('selected'), 0);
			}else if( $this->input->post('delete') ){
				$this->model->deleteItems($this->input->post('selected'));
			}
		}
		redirect(CMF_URL . $this->controller . '/' . $return);
	}
	
	function setLive($id = null){
		if( $id && is_numeric($id)){
			$this->model->setItemsLive($id);
		}
		//redirect('/admin/' . $this->model->getTable());
		redirect(CMF_URL . $this->controller);
	}
	
	function setNotLive($id = null){
		if( $id && is_numeric($id)){
			$this->model->setItemsLive($id, 0);
		}
		//redirect('/admin/' . $this->model->getTable());
		redirect(CMF_URL . $this->controller);
	}
	
	function archive($id = null){
		if( $id && is_numeric($id)){
			$this->model->archiveItems($id);
			$this->templateparser->setString($this->flash_messages['archive']);
			$this->session->set_flashdata('cmf_message', $this->templateparser->evalTemplate(array('id' => $id)));
		}
		//redirect('/admin/' . $this->model->getTable());
		redirect(CMF_URL . $this->controller);
	}
	
	function restore($id = null){
		if( $id && is_numeric($id)){
			$this->model->archiveItems($id, 0);
			$this->templateparser->setString($this->flash_messages['restore']);
			$this->session->set_flashdata('cmf_message', $this->templateparser->evalTemplate(array('id' => $id)));
		}
		//redirect('/admin/' . $this->model->getTable() . '/showarchive');
		redirect(CMF_URL . $this->controller . '/showarchive');
	}
	
	function getTableAndFieldData(&$data, $id = null){
		$data['table'] = $this->model->getTable();
		$data['table_name'] = $this->model->getTableName();
		$data['controller'] = $this->controller;
		$data['id_field'] = $this->model->getIdField();
		$data['fields'] = $this->model->getFields();
		$data['menu_view'] = isset($this->menu_view)?$this->menu_view:null;
		$this->model->prepareEditFields($id);
		$data['edit_fields'] = $this->model->getEditFields();
	}
	
	function saveSortOrder(){
		$this->model->saveSortOrder();
		$this->templateparser->setString($this->flash_messages['save_sort_order']);
		$this->session->set_flashdata('cmf_message', $this->templateparser->evalTemplate(array('id' => $id)));
		//redirect('/admin/' . $this->model->getTable());
		redirect(CMF_URL . $this->controller . '/');
	}
	
	function validateInput(){
		$this->load->library('form_validation');
		$this->form_validation->set_rules($this->model->getRules());
		return $this->form_validation->run();
	}
	
	function ajaxItemAccess($id){
		if( is_numeric($id) ){
			$query = $this->db->get_where( $this->table, array( $this->id_field => $id), 1);
			if( $query && $query->num_rows()){
				$query = $query->result_array();
				return json_encode($query);
			}
		}
		return null;
	}
	
	function error(){
		$this->load->view(CMF_DEFAULT_ERROR_VIEW);
	}
	
	function save($id = null, $ajax = 0){
		$ajax = $ajax || $this->input->post('ajax');
		if( $this->input->post('cancel') ){
			$this->model->cancelItem($id);
			$this->templateparser->setString($this->flash_messages['cancel']);
			$this->session->set_flashdata('cmf_message', $this->templateparser->evalTemplate(array('id' => $id)));
			//redirect('/admin/' . $this->model->getTable() );
			if( $ajax ){
				//$this->_popSessionImageUploads();
				return;
			}
			redirect(CMF_URL . $this->controller . '/');
		}else{
			if( count($_POST)){
				$data = array();
				if( $this->validateInput() === false){
					$view = CMF_DEFAULT_TABLE_EDIT_VIEW;
					if( $ajax ){
						$view = CMF_DEFAULT_TABLE_AJAX_EDIT_VIEW;
					}
					$this->onValidationFail($id, $view, $ajax);
				}else{
					$this->assembleData($data);
					$id = $this->model->saveItem($data, $id);
					$this->templateparser->setString($this->flash_messages['save']);
					$this->session->set_flashdata('cmf_message', $this->templateparser->evalTemplate(array('id' => $id)));
					if( $ajax ){
						//$this->_popSessionImageUploads();
						$data['id'] = $id;
						echo '1::' . json_encode($data);
						return;
					}
					if( $this->input->post('save') ){
						redirect(CMF_URL . $this->controller . '/');
					}else{
						redirect(CMF_URL . $this->controller . '/edit/' . $id);
					}
				}
			}else{
				//redirect('/admin/' . $this->model->getTable() );
				redirect(CMF_URL . $this->controller . '/');
			}
		}
	}
	
	function assembleData(&$data){
		$this->validationToArray($data);
	}
	
	function onValidationFail($id = null, $view = CMF_DEFAULT_TABLE_EDIT_VIEW, $ajax = false){
		$data = array();
		$this->load->helper('form');
		$this->getTableAndFieldData($data, $id);
		$this->createValidationItem($data);
		$data['item']->{$data['id_field']} = $id;
		if( !$ajax ){
			$this->edit( $id, $view, $data);
		}else{
			$this->editAjax( $id, $view, $data);
		}
		//$this->load->view($view, $data);
	}
	
	function createValidationItem(&$data){
		$item = array();
		$this->validationToArray($item);
		$data['item'] = (object)$item;
	}
	
	function validationToArray(&$data){
		$id_field = $this->model->getIdField();
		$fields = $this->model->getEditFields();
		foreach( $fields as $key => $value){
			if( $key != $id_field ){
				// set value escapes the text of the rich text editor, check post first
				if( isset($_POST[$key]) ){
					$data[$key] = $_POST[$key];
				}else{
					$data[$key] = set_value($key); // still need this for checkboxes
				}
			}
		}
	}
	
	function _get_id(){
		$s = $this->uri->segment(4);
		if( is_numeric($s) ){
			return $s;
		}else{
			return null;
		}
	}
}
?>